package com.zenithmind.mall.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.common.exception.BusinessException;
import com.zenithmind.mall.mapper.UserAddressMapper;
import com.zenithmind.mall.pojo.dto.UserAddressDTO;
import com.zenithmind.mall.pojo.entity.UserAddress;
import com.zenithmind.mall.pojo.vo.UserAddressVO;
import com.zenithmind.mall.service.UserAddressService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户地址服务实现
 * 
 * @author ZenithMind Team
 * @since 2025-06-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserAddressServiceImpl extends ServiceImpl<UserAddressMapper, UserAddress> implements UserAddressService {

    @Override
    public List<UserAddressVO> getUserAddressList(String userId) {
        LambdaQueryWrapper<UserAddress> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserAddress::getUserId, userId)
               .eq(UserAddress::getIsDeleted, 0)
               .orderByDesc(UserAddress::getIsDefault)
               .orderByDesc(UserAddress::getCreateTime);
        
        List<UserAddress> addresses = list(wrapper);
        return addresses.stream().map(this::convertToVO).collect(Collectors.toList());
    }

    @Override
    public UserAddressVO getDefaultAddress(String userId) {
        LambdaQueryWrapper<UserAddress> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserAddress::getUserId, userId)
               .eq(UserAddress::getIsDefault, 1)
               .eq(UserAddress::getIsDeleted, 0);
        
        UserAddress address = getOne(wrapper);
        return address != null ? convertToVO(address) : null;
    }

    @Override
    public UserAddressVO getAddressById(String id, String userId) {
        UserAddress address = getById(id);
        if (address == null || !address.getUserId().equals(userId)) {
            throw new BusinessException("地址不存在");
        }
        return convertToVO(address);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createAddress(UserAddressDTO addressDTO, String userId) {
        // 检查用户地址数量限制
        LambdaQueryWrapper<UserAddress> countWrapper = new LambdaQueryWrapper<>();
        countWrapper.eq(UserAddress::getUserId, userId)
                   .eq(UserAddress::getIsDeleted, 0);
        
        long addressCount = count(countWrapper);
        if (addressCount >= 20) { // 限制最多20个地址
            throw new BusinessException("地址数量已达上限");
        }

        UserAddress address = new UserAddress();
        BeanUtils.copyProperties(addressDTO, address);
        address.setUserId(userId);
        address.setCreateBy(userId);

        // 如果是第一个地址或者设置为默认地址，则设为默认
        if (addressCount == 0 || (addressDTO.getIsDefault() != null && addressDTO.getIsDefault() == 1)) {
            // 先清除其他默认地址
            clearOtherDefaultAddress(userId, null);
            address.setIsDefault(1);
        } else {
            address.setIsDefault(0);
        }

        if (!save(address)) {
            throw new BusinessException("创建地址失败");
        }

        log.info("用户 {} 创建地址成功: {}", userId, address.getId());
        return address.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateAddress(String id, UserAddressDTO addressDTO, String userId) {
        UserAddress existAddress = getById(id);
        if (existAddress == null || !existAddress.getUserId().equals(userId)) {
            throw new BusinessException("地址不存在");
        }

        UserAddress address = new UserAddress();
        BeanUtils.copyProperties(addressDTO, address);
        address.setId(id);
        address.setUpdateBy(userId);

        // 如果设置为默认地址，先清除其他默认地址
        if (addressDTO.getIsDefault() != null && addressDTO.getIsDefault() == 1) {
            clearOtherDefaultAddress(userId, id);
            address.setIsDefault(1);
        }

        boolean result = updateById(address);
        if (result) {
            log.info("用户 {} 更新地址成功: {}", userId, id);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteAddress(String id, String userId) {
        UserAddress address = getById(id);
        if (address == null || !address.getUserId().equals(userId)) {
            throw new BusinessException("地址不存在");
        }

        boolean result = removeById(id);
        if (result) {
            // 如果删除的是默认地址，需要设置新的默认地址
            if (address.getIsDefault() == 1) {
                setFirstAddressAsDefault(userId);
            }
            log.info("用户 {} 删除地址成功: {}", userId, id);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean setDefaultAddress(String id, String userId) {
        UserAddress address = getById(id);
        if (address == null || !address.getUserId().equals(userId)) {
            throw new BusinessException("地址不存在");
        }

        // 先清除其他默认地址
        clearOtherDefaultAddress(userId, id);

        // 设置当前地址为默认
        LambdaUpdateWrapper<UserAddress> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(UserAddress::getId, id)
               .set(UserAddress::getIsDefault, 1);

        boolean result = update(wrapper);
        if (result) {
            log.info("用户 {} 设置默认地址成功: {}", userId, id);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteAddressesBatch(List<String> ids, String userId) {
        if (ids == null || ids.isEmpty()) {
            return true;
        }

        // 验证所有地址都属于当前用户
        LambdaQueryWrapper<UserAddress> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(UserAddress::getId, ids)
               .eq(UserAddress::getUserId, userId)
               .eq(UserAddress::getIsDeleted, 0);

        List<UserAddress> addresses = list(wrapper);
        if (addresses.size() != ids.size()) {
            throw new BusinessException("部分地址不存在或无权限");
        }

        boolean hasDefault = addresses.stream().anyMatch(addr -> addr.getIsDefault() == 1);

        boolean result = removeByIds(ids);
        if (result) {
            // 如果删除了默认地址，需要设置新的默认地址
            if (hasDefault) {
                setFirstAddressAsDefault(userId);
            }
            log.info("用户 {} 批量删除地址成功，数量: {}", userId, ids.size());
        }
        return result;
    }

    /**
     * 清除其他默认地址
     */
    private void clearOtherDefaultAddress(String userId, String excludeId) {
        LambdaUpdateWrapper<UserAddress> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(UserAddress::getUserId, userId)
               .eq(UserAddress::getIsDefault, 1)
               .set(UserAddress::getIsDefault, 0);

        if (excludeId != null) {
            wrapper.ne(UserAddress::getId, excludeId);
        }

        update(wrapper);
    }

    /**
     * 设置第一个地址为默认地址
     */
    private void setFirstAddressAsDefault(String userId) {
        LambdaQueryWrapper<UserAddress> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserAddress::getUserId, userId)
               .eq(UserAddress::getIsDeleted, 0)
               .orderByDesc(UserAddress::getCreateTime)
               .last("LIMIT 1");

        UserAddress firstAddress = getOne(wrapper);
        if (firstAddress != null) {
            LambdaUpdateWrapper<UserAddress> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(UserAddress::getId, firstAddress.getId())
                        .set(UserAddress::getIsDefault, 1);
            update(updateWrapper);
        }
    }

    /**
     * 转换为VO
     */
    private UserAddressVO convertToVO(UserAddress address) {
        UserAddressVO vo = new UserAddressVO();
        BeanUtils.copyProperties(address, vo);
        
        // 拼接完整地址
        StringBuilder fullAddress = new StringBuilder();
        if (address.getProvince() != null) fullAddress.append(address.getProvince());
        if (address.getCity() != null) fullAddress.append(address.getCity());
        if (address.getDistrict() != null) fullAddress.append(address.getDistrict());
        if (address.getDetailAddress() != null) fullAddress.append(address.getDetailAddress());
        vo.setFullAddress(fullAddress.toString());
        
        return vo;
    }
}
